package websocket

import (
	"fmt"
	"peilian-api/app/global/log"
	"peilian-api/utils/function"
	"sync"
)

//Manager:所有websocket 信息

type Manager struct {
	//client.id => Client
	Group                map[string]*Client
	Lock                 sync.Mutex
	Register, UnRegister chan *Client
	BroadCastMessage     chan *BroadCastMessageData
	clientCount          uint //分组及客户端数量
}

// 初始化 wsManager 管理器

var WsManager = Manager{
	Group:            make(map[string]*Client),
	Register:         make(chan *Client, 500),
	UnRegister:       make(chan *Client, 500),
	BroadCastMessage: make(chan *BroadCastMessageData, 500),
	clientCount:      0,
}

//注册

func (manager *Manager) RegisterClient(client *Client) {
	manager.Register <- client
}

//注销

func (manager *Manager) UnRegisterClient(client *Client) {
	manager.UnRegister <- client
}

//启动websocket管理器

func (manager *Manager) Start() {
	log.Logger.Debug("websocket 服务器启动")
	for {
		select {
		case client := <-manager.Register:
			//注册客户端
			manager.Lock.Lock()
			manager.Group[client.Id] = client
			manager.clientCount += 1
			manager.Lock.Unlock()
			if manager.clientCount > 35 {
				log.Logger.InfoMsgF(client.Ctx, fmt.Sprintf("客户端注册: 客户端id为%s，连接用户数：%d", client.Id, manager.clientCount))
			} else {
				log.Logger.InfoF(client.Ctx, fmt.Sprintf("客户端注册: 客户端id为%s，连接用户数：%d", client.Id, manager.clientCount))
			}
			log.Logger.InfoF(client.Ctx, fmt.Sprintf("客户端注册: 客户端id为%s，连接用户数：%d", client.Id, manager.clientCount))
		case client := <-manager.UnRegister:
			log.Logger.InfoF(client.Ctx, fmt.Sprintf("客户端注销: 客户端id为%s", client.Id))
			//注销客户端
			manager.Lock.Lock()
			if _, ok := manager.Group[client.Id]; ok {
				//关闭消息通道
				close(client.Message)
				close(client.AudioCh)
				close(client.TextCh)
				//删除分组中客户
				delete(manager.Group, client.Id)
				//客户端数量减1
				manager.clientCount -= 1
				log.Logger.InfoF(client.Ctx, fmt.Sprintf("客户端注销: 客户端id为%s,连接用户数：%d", client.Id, manager.clientCount))
			}
			manager.Lock.Unlock()
		case data := <-manager.BroadCastMessage:
			//将数据广播给所有客户端
			for _, conn := range manager.Group {
				if data.IsBroadCast {
					conn.Message <- data.Message
				} else {
					if function.InSliceStr(conn.Id, data.ClientIDs) {
						conn.Message <- data.Message
					}
				}

			}

		}
	}
}
